#ifndef LIB_H_INCLUDED
#define LIB_H_INCLUDED

#include "runtime.h"

#define C_FUN_NB 11 // Nombre de fonctions implanté par l'interprete

/*********************************/

int16_t print_int(int16_t arg){
    printf("%d\n", arg >> 1);
    return UNIT;
}

int16_t int_of_string(int16_t arg){
    return atoi((char *)get_field(arg, 0));
}

int16_t caml_format_int(int16_t arg1 , int16_t arg2)
{
    printf("=====================\n ========================\n FORMAT INT ====================== \n ================= \n");
    printf("%d",get_value(arg2));
    return UNIT;
}

int16_t caml_ml_string_length(int16_t s)
{
  int16_t size = get_size(s);
  return size*2;
}

int16_t delay(int16_t time)
{
    printf("======= delay %d ========== \n" , get_value(time));
    return UNIT;
}

int16_t digital_read( int16_t pin )
{
    printf("========== Digital read pin %d ========== \n", get_value(pin));
    return UNIT;
}

int16_t digital_write( int16_t pin , int16_t value)
{
    printf("=========== Digital write pin %d value %d ========== \n" , get_value(pin) , get_value(value));
    return UNIT;
}

int16_t analog_write( int16_t pin , int16_t value )
{
    printf("============= analog write pin %d  value %d ========= \n",get_value(pin), get_value(value));
    return UNIT;
}

int16_t analog_read( int16_t pin )
{
    printf("============= analog read pin %d =============== \n", get_value(pin));
    return UNIT;
}

int16_t set_pin_mode( int16_t pin , int16_t mode)
{
    printf("===============set pin mode pin %d mode %d ========= \n ",get_value(pin),get_value(mode));
    return UNIT;
}

int16_t serial_begin( int16_t value )
{
    printf("================ serial begin %d ============= \n", get_value(value));
    return UNIT;
}

int16_t serial_println( int16_t value )
{
    printf("================= serial println %d ==============\n", get_value(value));
    return UNIT;
}

int16_t caml_ml_output_char(int16_t arg1 , int16_t arg2)
{
    printf("=====================\n ========================\n ML OUTPUT CHAR ====================== \n ================= \n");
    printf("%c %c",arg1,arg2);
    return UNIT;
}

int16_t caml_ml_output(int16_t arg1 , int16_t arg2,int16_t arg3 , int16_t arg4)
{
     printf("=====================\n ========================\n OUTPUT ====================== \n ================= \n");
     print_element(arg1);
     print_element(arg2);
     print_element(arg3);
     print_element(arg4);
     if((arg2 & 0x0001) == 0)
     {
         unsigned char c1,c2;
         unsigned char * s;
         int i = 0;
         int16_t j = 0;
         for(i=0 ; i< get_size(arg2);i++)
         {
             j = (*(get_field(arg2,i)));
             //printf("%X\n",Field(arg2,i));
             printf("%X\n",j);
         }

         for(i=0;i<get_size(arg2)*2;i++)
         {
             printf("%c\n",get_char(arg2,i));
         }
         s = ((unsigned char *)((get_field(arg2,0))));
         //printf("%d",get_size(arg2));
         printf("%s\n",s);
     }
   // printf("%s\n",arg2);
    return UNIT;
}


typedef int16_t (*c_fun)();

// Noms des primitives disponible

char *c_fnames[C_FUN_NB] = {
  "int_of_string",
  "print_int",
  "caml_format_int",
 "caml_ml_output_char",
 "caml_ml_output",
  "delay",
  "digital_read",
  "digital_write",
  "analog_read",
  "analog_write",
  "set_pin_mode",
  "serial_begin",
  "serial_println"
};

// Pointeurs vers les fonctions

c_fun c_funs[C_FUN_NB] = {
  (c_fun) &int_of_string,
  (c_fun) &print_int,
  (c_fun) &caml_format_int,
  (c_fun) &caml_ml_output_char,
  (c_fun) &caml_ml_output,
  (c_fun) &delay,
  (c_fun) &digital_read,
  (c_fun) &digital_write,
  (c_fun) &analog_read,
  (c_fun) &analog_write,
  (c_fun) &set_pin_mode,
  (c_fun) &serial_begin,
  (c_fun) &serial_println
};

c_fun * bytecode_funs; // Tableau des primitives, initialise dans init_prim()



#endif // LIB_H_INCLUDED
